package com.xaicode.template.sqlite3.controller;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.RuntimeUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.xaicode.template.sqlite3.entity.Airport;
import com.xaicode.template.sqlite3.entity.AirportPlane;
import com.xaicode.template.sqlite3.service.IAirportPlaneService;
import com.xaicode.template.sqlite3.service.IAirportService;
import com.xaicode.template.sqlite3.service.IPlaneService;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author xiachangjian <xiachangjian@sataero.cn>
 * @date 2023/1/29
 * @since v2.0.1
 */
@RestController
@RequestMapping
@Slf4j
public class IndexController {

    @Resource
    private IAirportService airportService;

    @Resource
    private IPlaneService planeService;

    @Resource
    private IAirportPlaneService airportPlaneService;

    /**
     * 多数据源的统一事务验证
     * 
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @GetMapping("testTx")
    public String testTx() {
        // 事务测试

        airportService.addOne();

        planeService.addOne();

        // throw new RuntimeException("test transactional =================");
        return "testTx";
    }

    /**
     * 基于原子锁的实现，数据库文件更换期间锁定执行，
     * 但仅适用于单个任务。
     * 
     * @return .
     */
    // @Scheduled(cron = "0/10 * * * * ?")
    @GetMapping("t1")
    public String t1() {

        List<Airport> airports = airportService.list();
        System.out.println(airports.size() + " =================");

        AtomicBoolean modDB = new AtomicBoolean(true);

        ThreadUtil.execute(new Runnable() {
            @Override
            public void run() {
                RuntimeUtil.exec("mv /root/db/test-db/test-base.db /root/db/test-db/test-base.db.m1");
                System.out.println("mv /root/db/test-db/test-base.db /root/db/test-db/test-base.db.m1");

                RuntimeUtil.exec("mv /root/db/test-db/test-base.db.m1 /root/db/test-db/test-base.db");
                System.out.println("mv /root/db/test-db/test-base.db.m1 /root/db/test-db/test-base.db");

                modDB.set(false);
            }
        });

        try {
            while (modDB.get()) {
                ThreadUtil.safeSleep(500);
                System.out.println("======= modDB 正在运行 ========");
            }

            System.out.println("======= modDB 运行完毕 ========");
            airportService.addOne();
            System.out.println("======= addOne 运行完毕 ========");
        } catch (Exception e) {
            log.error("addOne fail, cause: {}", e.toString());
        }

        System.out.println(airportService.count() + " -------------------------");
        return "1";
    }

    @GetMapping("t2")
    public String t2() {

        














        return "2";
    }

}
